Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

If I have a 2 D matrix of any size say

$\left( \begin{array}{ccc} 72 & 32 & 64 \\ 18 & 8 & 16 \\ 63 & 28 & 56 \\ \end{array} \right)$

$\left( \begin{array}{cc} 72 & 32 \\ 18 & 8 \\ 63 & 28 \\ \end{array} \right)$

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

enter image description here enter image description here

$\left( \begin{array}{ccccc} 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{array} \right)$

$\left( \begin{array}{cccc} 0 & 32 & 0 & 0 \\ 72 & 0 & 8 & 0 \\ 0 & 18 & 0 & 28 \\ 0 & 0 & 63 & 0 \\ \end{array} \right)$

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 http://en.wikipedia.org/wiki/Lattice_multiplication for further details

share|improve this question
3  
Great question. :-) – Mr.Wizard Apr 7 at 5:29
Out of general interest, why do you want to know? – Lucas Apr 7 at 15:15
@Lucas please see updated details – Prashant Bhate Apr 7 at 17:42
@PrashantBhate Aha, thanks. – Lucas Apr 8 at 1:01

6 Answers

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]]]]
share|improve this answer
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}]]
share|improve this answer

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
share|improve this answer
1  
Slightly shorter, and theoretically one less operation: Band[{0, Length@m - 1} + #2[[1]], Automatic, {1, -1}] & – Mr.Wizard Apr 7 at 8:17

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

share|improve this answer

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
share|improve this answer

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}} *)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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