MATLAB finally updated its array compatibility to match Python

2 minute read

Matlab finally embraces (partially) the way matrix manipulation should be

Starting in MATLAB R2016b with the addition of implicit expansion, some combinations of arguments for basic operations that previously returned errors now produce results. This extremely simplifies some codes used in vectorization.

For example, you previously could not add a row and a column vector, but those operands are now valid for addition. In other words, an expression like [1 2] + [1; 2] previously returned a size mismatch error, but now it executes.

If your code uses element-wise operators and relies on the errors that MATLAB previously returned for mismatched sizes, particularly within a try/catch block, then your code might no longer catch those errors.

For example,

[1 2; 3 4].*[2 3]


ans =
     2     6
     6    12

If now you have a matrix

[1 2; 3 4].*[2; 3]


ans =
     2     4
     9    12

This puts MATLAB’s array manipulation behavior almost identical with numpy.

More examples and a comparison with the old implementation

Suppose you have a bunch of points given in the form of

p = [1 2; 
     3 4;
     5 6];
pbar = mean(p,1); 

where pbar = [3, 4] is the average of p along dimension 1 (row vector, as the 1st dimension has being summed out). Originally if you want to have p normalized row-wise, to achieve the following code block of for:

pn = zeros(size(p));
for i = 1:size(p,1)
    pn(i,:) = p(i,:) - pbar(i);

You need to use repmat to match the dimension of pbar with p first, and then initiate the subtraction:

pbar = repmat(pbar, [size(p,1) 1]);
pn = p - pbar;

Aside from inconvenience of calling this function along, using repmat with a hard-coded dimension input brings extra hassle to the debugging process as the code now behaves differently for row and column vectors. You have to be able to track through the dimensions along your code, this defeats the purpose of a clean code.

After MATLAB 2016b, it is just one line without the repmat:

pn = p - pbar

ans =
    -2    -2
     0     0
     2     2

A final remark of MATLAB vs numpy

One thing I like about numpy is that it auto-squeezes 1 dimensional vector in that it does not anything to transpose if the shape of an ndarray is say (10, ). Unless you manually expand dimension in numpy, the behavior of @ in Python 3 is pretty favorable in my opinion.

MATLAB however, does not do this, there is no array with a size of (10, ), you either have (10, 1) or (1, 10), and sometimes in vectorized routine, it is necessary to use isrow kind of function to do manual checks.