How to decompose 2D (m*n, m*n) matrix into 4D (m, m, n, n) matrix in Python?
I'll try to illustrate the issues discussed in the comments.
A starting array - a reshape of a 1d arange:
In [160]: arr = np.arange(16).reshape(4,4)
In [161]: arr
Out[161]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [162]: arr.ravel()
Out[162]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
In [163]: arr.strides
Out[163]: (32, 8)
Further reshape to 4d. Note the ravel
is the same. I could also use arr2.__array_interface__
to show the data buffer id.
In [164]: arr1 = arr.reshape(2,2,2,2)
In [165]: arr1.ravel()
Out[165]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
In [166]: arr1.strides
Out[166]: (64, 32, 16, 8)
It's would be a good idea to test your understanding of the change in strides with change in shape.
Now swap:
In [167]: arr2 = arr1.swapaxes(1,2)
In [168]: arr2
Out[168]:
array([[[[ 0, 1],
[ 4, 5]],
[[ 2, 3],
[ 6, 7]]],
[[[ 8, 9],
[12, 13]],
[[10, 11],
[14, 15]]]])
In [169]: arr2.strides
Out[169]: (64, 16, 32, 8)
Still a (2,2,2,2) but strides has changed. This too is a view. But a reshape of this (including a ravel) will make a copy. The elements have been reordered:
In [170]: arr2.ravel()
Out[170]: array([ 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15])
In [171]: arr3 = arr2.reshape(4,4)
In [172]: arr3
Out[172]:
array([[ 0, 1, 4, 5],
[ 2, 3, 6, 7],
[ 8, 9, 12, 13],
[10, 11, 14, 15]])
In [173]: arr3.ravel()
Out[173]: array([ 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15])
We see the same change in strides in a simpler 2d transpose:
In [174]: arr4 = arr.T
In [175]: arr4.strides
Out[175]: (8, 32)
In [176]: arr4.ravel()
Out[176]: array([ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15])
We can make a view
ravel by specifying the 'F' column order. Though that may not help with the understanding. Order does not readily extend to higher dimensions, but strides does.
In [177]: arr4.ravel(order='F')
Out[177]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])