15
$\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$
  • 3
    $\begingroup$ Great question. :-) $\endgroup$ – Mr.Wizard Apr 7 '13 at 5:29
  • $\begingroup$ Out of general interest, why do you want to know? $\endgroup$ – Lucas Apr 7 '13 at 15:15
  • $\begingroup$ @Lucas please see updated details $\endgroup$ – Prashant Bhate Apr 7 '13 at 17:42
  • $\begingroup$ @PrashantBhate Aha, thanks. $\endgroup$ – Lucas Apr 8 '13 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 Sep 18 '13 at 18:31
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
    $\begingroup$ Slightly shorter, and theoretically one less operation: Band[{0, Length@m - 1} + #2[[1]], Automatic, {1, -1}] & $\endgroup$ – Mr.Wizard Apr 7 '13 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, privacy policy and cookie policy

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