2013-07-28

multidimensional copy in MATLAB's repmat() and NumPy's tile()

repmat is a MATLAB function. A while ago, I had to translate a MATLAB script into Python and it had a lot of repmat(). However, the doc "NumPy for MATLAB Users" only covers the case to duplicate a matrix in 2D, e.g., repmat(a, m, n). How about repmat(a, [m n p])?

The answer is
numpy.array([np.tile(x, (m,n)) for i in xrange(p)])
Please see my demo below. Please also note that using nested tile, i.e.,
np.tile(np.tile(x, (2,2)), (1,3))
does not help-you still get a 2D matrix.

In [1]: import numpy as np

In [2]: x=np.array([[1,2,3],[4,5,6]])

In [3]: np.tile(x, (2,2))
Out[3]: 
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

In [4]: np.tile(np.tile(x, (2,2)), (1,3))
Out[4]: 
array([[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]])

In [5]: np.tile(np.tile(x, (2,2)), (3,1))
Out[5]: 
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

In [6]: np.array([np.tile(x, (2,2)) for i in xrange(3)])
Out[6]: 
array([[[1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6],
        [1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6]],

       [[1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6],
        [1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6]],

       [[1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6],
        [1, 2, 3, 1, 2, 3],
        [4, 5, 6, 4, 5, 6]]])


in MATLAB
>> repmat(x, [2,2,3])

ans(:,:,1) =

1     2     3     1     2     3
4     5     6     4     5     6
1     2     3     1     2     3
4     5     6     4     5     6


ans(:,:,2) =

1     2     3     1     2     3
4     5     6     4     5     6
1     2     3     1     2     3
4     5     6     4     5     6


ans(:,:,3) =

1     2     3     1     2     3
4     5     6     4     5     6
1     2     3     1     2     3
4     5     6     4     5     6

No comments: