16
$\begingroup$

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

diagram for rotating a matrix another diagram

$\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

$\endgroup$
6
  • 4
    $\begingroup$ Great question. :-) $\endgroup$
    – Mr.Wizard
    Commented Apr 7, 2013 at 5:29
  • $\begingroup$ Out of general interest, why do you want to know? $\endgroup$
    – Lucas
    Commented Apr 7, 2013 at 15:15
  • $\begingroup$ @Lucas please see updated details $\endgroup$ Commented Apr 7, 2013 at 17:42
  • $\begingroup$ @PrashantBhate Aha, thanks. $\endgroup$
    – Lucas
    Commented Apr 8, 2013 at 1:01
  • $\begingroup$ @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? $\endgroup$
    – Mr.Wizard
    Commented Sep 18, 2013 at 18:31

6 Answers 6

14
$\begingroup$
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

enter image description here

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

enter image description here

mtrx = Partition[CharacterRange["a", "x"], 4];
mtrx // MatrixForm

enter image description here

Row[MatrixForm@rttF[mtrx[[;; #, All]]] & /@ {2, 3, 4, 5, 6}]

enter image description here

Row[MatrixForm@rttF[mtrx[[All, ;; #]]] & /@ {2, 3, 4}]

enter image description here

Update 2: shorter version:

rttF2 = Function[{mat}, With[{m = Last@Dimensions[mat]},
   SparseArray[Band[{m + 1 - #, #}] -> Transpose[mat][[#]] & /@ Range[m]]]]
$\endgroup$
9
$\begingroup$
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}]]
$\endgroup$
7
$\begingroup$

For any number of dimensions ( two versions):

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

or (keeping it short)

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


s = {{72, 32, 64}, {18, 8, 16}, {63, 28, 56}}
MatrixForm@rot[s]

kguler already uploaded i

$\endgroup$
6
$\begingroup$

This works with matrix of any size (remove Reverse to get it in other direction)

rotate45[m_] := 
 SparseArray@
  MapIndexed[
   Band[{#2[[1]], Length@m + #2[[1]] - 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
$\endgroup$
1
  • 1
    $\begingroup$ Slightly shorter, and theoretically one less operation: Band[{0, Length@m - 1} + #2[[1]], Automatic, {1, -1}] & $\endgroup$
    – Mr.Wizard
    Commented Apr 7, 2013 at 8:17
4
$\begingroup$

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

An old-fashioned I guess rotation of indices.

Turn[m_?MatrixQ] :=
 With[{ax = {1, Length[First@m]}},
    MapIndexed[Round[Composition[
          ScalingTransform[Sqrt[2] {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}} *)
$\endgroup$

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.