Friday 7 August 2015

Matlab's repmat in Python

This post is partly to remind myself of this, partly for others who might find themselves in a similar situation. I find myself wanting to use a repmat function in Python - used as I am to Matlab's syntax. A quick search will tell you that the function to use is numpy.tile, and that's indeed true.

But, say that you have an image of shape (1024,512) and you'd like it to become (1024,512,3). What's the way to go? In Matlab you would just say

B = repmat(A,[1,1,3]);

and if you try that with np.tile you'll find that B has shape (1,1024,1536). Somehow, it's added a new dimension at the beginning, not at the end!

To obtain the same behaviour as Matlab, you have to do

B = np.tile(A.reshape(1024,512,1), (1,1,3))

In practice you're explicitly adding a dimension to the array A before tiling it.

Having said that, numpy does something that Matlab doesn't: it broadcasts operators. So if you have two arrays of different dimensions, numpy can automatically repeat the same operation (a bit like Matlab's bsxfun). The catch is that the operation is repeated over the first dimension of the array. So let's say we want to add A of shape (1024,512) and B of shape (1024,512,3). The way I'd go about doing that is with transposes:

C = A.T + B.T
C = C.T

Transposition in numpy is more generic than in Matlab and can be applied to n-dimensional arrays. It changes the dimensions so that that an array of size w,x,y,z its transpose will have size z,y,x,w. So that's now adding matrices of shapes (512,1024) and (3,512,1024), which works because the broadcasting happens along the first dimension. Then, of course, the result needs to be transposed back.

1 comment: